package com.smsc.headend.connector.netty.initializer;

import cn.hutool.extra.spring.SpringUtil;
import com.smsc.headend.common.thread.UDISThreadFactory;
import com.smsc.headend.connector.netty.decoder.BytesInboundCounter;
import com.smsc.headend.connector.netty.decoder.cosem.CosemByteDecoder;
import com.smsc.headend.connector.netty.decoder.DecodeProxy;
import com.smsc.headend.connector.netty.encoder.CosemEncoder;
import com.smsc.headend.connector.netty.handler.BytesOutboundCounter;
import com.smsc.headend.connector.netty.handler.DLMSPacketHandler;
import com.smsc.headend.connector.service.DeviceConnectService;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.RejectedExecutionHandler;
import io.netty.util.concurrent.SingleThreadEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;


@Slf4j
public class COSEMServerInitializer extends ChannelInitializer<SocketChannel> {
    @Autowired
    DeviceConnectService deviceConnectService;


    @Override
    protected void initChannel(SocketChannel socketChannel) {
//        EventExecutorGroup eventExecutors = new DefaultEventExecutorGroup(32, new UDISThreadFactory("device"), 200000, new RejectedExecutionHandler() {
//            @Override
//            public void rejected(Runnable runnable, SingleThreadEventExecutor singleThreadEventExecutor) {
//                log.warn("receivePacketOverlimit,discard");
//                deviceConnectService.stopTaskAccept();
//            }
//        });


        AutowireCapableBeanFactory autowireCapableBeanFactory = SpringUtil.getApplicationContext().getAutowireCapableBeanFactory();
        DLMSPacketHandler handler = new DLMSPacketHandler();
        BytesInboundCounter inboundCounter = new BytesInboundCounter();
        BytesOutboundCounter outboundCounter = new BytesOutboundCounter();
        CosemEncoder cosemEncoder = new CosemEncoder();
        autowireCapableBeanFactory.autowireBean(cosemEncoder);
        autowireCapableBeanFactory.autowireBean(handler);
        autowireCapableBeanFactory.autowireBean(inboundCounter);
        autowireCapableBeanFactory.autowireBean(outboundCounter);
        ChannelPipeline pipeline = socketChannel.pipeline();
        pipeline.addLast("encoder", cosemEncoder);
        pipeline.addLast("decoder", new DecodeProxy());
        pipeline.addLast("inboundCounter", inboundCounter);
//        pipeline.addLast("bytesOutboundCounter", outboundCounter);
        pipeline.addLast("cosemDecode", new CosemByteDecoder());
        pipeline.addLast(new IdleStateHandler(15, 15, 30), handler);
//        pipeline.addLast("outboundCounter", outboundCounter);
    }
}
